package org.rainbowinverted.charging.device.connect.bl.server.handler;

import cn.hutool.core.util.HexUtil;
import com.dix.codec.bkv.BKV;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.rainbowinverted.charging.device.connect.bl.server.message.in.BlDeviceChargeFinishIn;
import org.rainbowinverted.charging.device.connect.bl.server.message.in.BlDeviceChargeFinishReasonIn;
import org.rainbowinverted.charging.device.connect.bl.server.message.in.BlDeviceGunChargeInfoIn;
import org.rainbowinverted.charging.device.connect.bl.server.message.in.BlDeviceGunInfoIn;
import org.rainbowinverted.charging.device.connect.bl.server.message.out.BlDeviceChargeFinishOut;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 充电结束处理器
 *
 * @author huaiping
 */
@Slf4j
@Component
@AllArgsConstructor
@ChannelHandler.Sharable
public class BlChargeFinishHandler extends BlAbstractHandler<BlDeviceChargeFinishIn, BlDeviceChargeFinishOut> {

    private BlGunInfoMessageHandler blGunInfoMessageHandler;

    @Override
    public void write(BlDeviceChargeFinishOut message, BKV bkv) {
        addAck(bkv, message.getAck());
    }

    @Override
    public void read(ChannelHandlerContext channelHandlerContext, BKV bkv) {
        Long serialNo = getSerialNo(bkv);
        Long deviceNo = getDeviceNo(bkv);
        // 充电功率信息
        BlDeviceGunChargeInfoIn gunChargeInfo = blGunInfoMessageHandler.gunPowerInfoDecode(bkv);
        // 充电枪信息
        BlDeviceGunInfoIn gunInfo = blGunInfoMessageHandler.gunInfoDecode(bkv);
        /*
            充电枪结束原因
            0----金额用完
            1----远程结束
            2----刷卡主动结束
            3----车端结束充电
            4----漏电结束
            5----过温结束
            6----电表通讯异常结束
            7----充满停止
            8----拔枪停止
            9----急停按钮按下
            a----过载结束
            b—---空载结束
            c—---时间用完
            d----电量用完
         */
        byte chargeFinishReason = Byte.parseByte(HexUtil.encodeHexStr(bkv.get(0x78).getValue()), 16);
        BlDeviceChargeFinishReasonIn finishReason = BlDeviceChargeFinishReasonIn.builder()
                .balanceInsufficient(chargeFinishReason == 0x00)
                .remoteClose(chargeFinishReason == 0x01)
                .cardManualClose(chargeFinishReason == 0x02)
                .terminalClose(chargeFinishReason == 0x03)
                .leakElectricity(chargeFinishReason == 0x04)
                .overTemp(chargeFinishReason == 0x05)
                .meterError(chargeFinishReason == 0x06)
                .batteryFull(chargeFinishReason == 0x07)
                .pullOutGun(chargeFinishReason == 0x08)
                .emergencyButton(chargeFinishReason == 0x09)
                .overload(chargeFinishReason == 0x0a)
                .idling(chargeFinishReason == 0x0b)
                .outOfTime(chargeFinishReason == 0x0c)
                .outOfPower(chargeFinishReason == 0x0d).build();
        // 费用信息
        int electricityFee = Integer.parseInt(HexUtil.encodeHexStr(bkv.get(0x85).getValue()), 16);
        int serviceFee = Integer.parseInt(HexUtil.encodeHexStr(bkv.get(0x86).getValue()), 16);
        BlDeviceChargeFinishIn chargeDetailReportDTO = BlDeviceChargeFinishIn.
                of(deviceNo,gunInfo, gunChargeInfo, finishReason, electricityFee, serviceFee,LocalDateTime.now());
        // 确认命令
        channelHandlerContext.writeAndFlush(new BlDeviceChargeFinishOut(serialNo, deviceNo, (byte) 0x01));
        log.info("charge finish info : {}", chargeDetailReportDTO);
    }
}
